From Conrad Meyer:
authorrobertlipe <robertlipe@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 7 Aug 2013 19:06:32 +0000 (19:06 +0000)
committerrobertlipe <robertlipe@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Wed, 7 Aug 2013 19:06:32 +0000 (19:06 +0000)
- Nuke leftover HAVE_EXPAT garbage in google.cc
- Use file prefix to attempt to discover HTML encoding
- Slurp entire HTML input file as discovered encoding, then pass to
  QXmlStreamReader as a QString

xmlgeneric:
- Adds a new function, void xml_readunicode(const QString& str) (does
  what you'd expect -- feeds QString input into the xml parser and runs
  it)

git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@4519 f51c46e8-681c-474f-0cfe-069cfd0219fb

gpsbabel/defs.h
gpsbabel/google.cc
gpsbabel/xmlgeneric.cc
gpsbabel/xmlgeneric.h

index e0eb3cd06637c5680c456b396b0ae3cf6bba47a8..6380c69416b43f1828735ddf555b9307274a881e 100644 (file)
@@ -36,7 +36,7 @@
 #include "inifile.h"
 #include "session.h"
 
-#include <Qtcore/QString>
+#include <QtCore/QString>
 #include <QtCore/QDebug>
 
 # include "src/core/datetime.h"
index ed1387f365234684013a0535c573c9b3cd391ae2..99ec30004bc02666eeb059095f00ef7b20425d42 100644 (file)
@@ -17,6 +17,7 @@
 
  */
 
+#include <QtCore/QFile>
 #include <QtCore/QXmlStreamAttributes>
 
 #include "defs.h"
@@ -28,25 +29,13 @@ static char* script = NULL;
 static route_head** routehead;
 static int* routecount;
 static short_handle desc_handle;
+static const char* rd_fname;
 
 static int serial = 0;
 
 #define MYNAME "google"
 #define MY_CBUF 4096
 
-#if ! HAVE_LIBEXPAT
-static void
-google_rd_init(const char* fname)
-{
-  fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n");
-}
-
-static void
-google_read(void)
-{
-}
-#else
-
 static xg_callback      goog_points, goog_levels, goog_poly_e, goog_script;
 static xg_callback     goog_segment_s, goog_segment, goog_td_s, goog_td_b;
 static xg_callback     goog_td_e;
@@ -259,19 +248,63 @@ void goog_poly_e(const char* args, const QXmlStreamAttributes *unused)
 static void
 google_rd_init(const char* fname)
 {
+  rd_fname = fname;
+
   desc_handle = mkshort_new_handle();
   setshort_length(desc_handle, 12);
 
   xml_init(fname, google_map, NULL);
 }
 
+static void
+goog_read_file(void)
+{
+  QFile src(QString::fromUtf8(rd_fname));
+
+  src.open(QIODevice::ReadOnly);
+
+  QTextStream tstr(&src);
+  tstr.setCodec("ISO-8859-1");
+
+  QString preamble = tstr.read(256);
+  QString needle("http-equiv=\"content-type\" content=\"text/html; charset=");
+
+  if (!preamble.contains(needle)) {
+    // let QXmlStreamReader do its best if we can't figure it out...
+    xml_read();
+    return;
+  }
+
+  int idx = preamble.indexOf(needle);
+  QString charset = preamble.mid(idx + needle.length());
+
+  int endq = charset.indexOf('"');
+  if (endq != -1) {
+    charset = charset.left(endq);
+  }
+
+  QString wholefile;
+  if (charset == "ISO-8859-1") {
+    wholefile = preamble + tstr.readAll();
+  } else {
+    tstr.reset();
+    tstr.seek(0);
+    tstr.setCodec(CSTR(charset));
+    wholefile = tstr.readAll();
+  }
+
+  xml_readunicode(wholefile);
+}
+
 static void
 google_read(void)
 {
   routehead = (route_head**)xmalloc(sizeof(route_head*));
   routecount = (int*)xmalloc(sizeof(int));
   goog_segroute = 0;
-  xml_read();
+
+  goog_read_file();
+
   xfree(routehead);
   xfree(routecount);
   routehead = NULL;
@@ -512,7 +545,6 @@ google_read(void)
     encoded_levels = NULL;
   }
 }
-#endif
 
 static void
 google_rd_deinit(void)
index 88717f1a48ebfe75be073881245c1eccb9f72845..abd712d167b4e545ce44e2db7446940d55731244 100644 (file)
@@ -272,11 +272,15 @@ void xml_ignore_tags(const char** taglist)
   }
 }
 
+// Chucks some bytes into the global QByteArray buffer and waits for
+// xml_readstring() to parse.
 void xml_readprefixstring(const char* str)
 {
   reader_data.append(str);
 }
 
+// Parses a bytestream as if it were a file. Looks for an <?xml encoding= to
+// determine file encoding, falls back to UTF-8 if unspecified.
 void xml_readstring(const char* str)
 {
   QString current_tag;
@@ -288,4 +292,14 @@ void xml_readstring(const char* str)
   xml_run_parser(reader, current_tag);
 }
 
+// This is quite different from xml_readstring(). It doesn't have to interpret
+// encoding because the source is already Qt's internal UTF-16.
+void xml_readunicode(const QString& str)
+{
+  QString current_tag;
+  QXmlStreamReader reader(str);
+
+  xml_run_parser(reader, current_tag);
+}
+
 /******************************************/
index c725724a34ca1b8bcf2d188887c8c1b45ab74a96..d2897f0ddb11f6f99b8fce5d13eed03a17fd9acd 100644 (file)
@@ -61,4 +61,5 @@ void xml_init_offset(const char* fname, xg_tag_mapping* tbl,
 void xml_read(void);
 void xml_readstring(const char* str);
 void xml_readprefixstring(const char* str);
+void xml_readunicode(const QString& str);
 void xml_deinit(void);